package com.inspinia.auth.sso.client.controller;

import com.baomidou.kisso.AuthToken;
import com.baomidou.kisso.SSOConfig;
import com.baomidou.kisso.SSOHelper;
import com.baomidou.kisso.SSOToken;
import com.baomidou.kisso.common.SSOProperties;
import com.inspinia.auth.common.util.AjaxHelper;
import com.inspinia.base.util.CookieUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class SsoClientController {

    protected Logger logger = LoggerFactory.getLogger(SsoClientController.class);

    protected String redirectTo(String url) {
        StringBuffer rto = new StringBuffer("redirect:");
        rto.append(url);
        return rto.toString();
    }

    /**
     * 跨域登录
     */
    @RequestMapping("/proxylogin")
    public String proxylogin(Model model, HttpServletRequest request, HttpServletResponse response) {
        /**
         *
         * 用户自定义配置获取
         *
         * <p>
         * 由于不确定性，kisso 提倡，用户自己定义配置。
         * </p>
         *
         */
        SSOProperties prop = SSOConfig.getSSOProperties();

        //业务系统私钥签名 authToken 自动设置临时会话 cookie 授权后自动销毁
        AuthToken at = SSOHelper.askCiphertext(request, response, prop.get("sso.defined.my_private_key"));

        //at.getUuid() 作为 key 设置 authToken 至分布式缓存中，然后 sso 系统二次验证

        //askurl 询问 sso 是否登录地址
        model.addAttribute("askurl", prop.get("sso.defined.askurl"));

        //askTxt 询问 token 密文
        model.addAttribute("askData", at.encryptAuthToken());

        //my 确定是否登录地址
        model.addAttribute("okurl", prop.get("sso.defined.oklogin"));

        //logout
        model.addAttribute("logouturl","logout");
        return "sso/proxylogin";
    }

    /**
     * 跨域登录成功
     */
    @ResponseBody
    @RequestMapping("/oklogin")
    public void oklogin( HttpServletRequest request,HttpServletResponse response) {
        SSOProperties prop = SSOConfig.getSSOProperties();
        String returl =prop.get("sso.logout.url");
        /*
         * <p>
         * 回复密文是否存在
         * </p>
         * <p>
         * SSO 公钥验证回复密文是否正确
         * </p>
         * <p>
         * 设置 业务系统自己的 Cookie
         * </p>
         */
        String replyTxt = request.getParameter("replyTxt");
        if (replyTxt != null && !"".equals(replyTxt)) {


            AuthToken at = SSOHelper.ok(request, response, replyTxt, prop.get("sso.defined.my_public_key"),
                    prop.get("sso.defined.sso_public_key"));

            if (at != null) {
                returl = prop.get("sso.defined.clientIndex");
                SSOToken st = new SSOToken();
                st.setUid(at.getUid());
                st.setTime(at.getTime());
                st.setId(at.getId());
                st.setData(at.getData());

                //写入新的票据
                SSOHelper.setSSOCookie(request, response, st, false);

                //把服务端的sessionid写到本地，交给spring-session管理
                CookieUtils.addHttpOnlyCookie(response,new Cookie("SESSION", st.getId().toString()));
            }
        }
        try {
            AjaxHelper.outPrint(response, "{\"returl\":\"" + returl + "\"}", "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 跨域登录超时
     */
    @RequestMapping("/timeout")
    public String timeout() {
        return "timeout";
    }
}